package de.haw.gka.a1;


import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Rectangle;
import java.awt.geom.Rectangle2D;

import java.util.HashSet;
import java.util.Iterator;

import java.util.Random;
import java.util.Set;

import javax.swing.JPanel;
import javax.swing.JScrollPane;

import org.jgraph.JGraph;
import org.jgraph.graph.AttributeMap;
import org.jgraph.graph.DefaultGraphCell;
import org.jgraph.graph.GraphConstants;
import org.jgrapht.ext.JGraphModelAdapter;
import org.jgrapht.graph.AbstractGraph;
import org.jgrapht.graph.DefaultEdge;
import org.jgrapht.graph.DefaultWeightedEdge;



public class ViewGraph extends JPanel{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

    private boolean isBig = false;
	private JGraphModelAdapter<?, ?> graphAdapter;
	private Set<Integer> xset = new HashSet<Integer>();
	private Set<Integer> ySet = new HashSet<Integer>();
	
	private boolean isDefaultEgde = false;
	private boolean isString = false;
    private JScrollPane scrollPane = new JScrollPane();
	
	public ViewGraph(String titel, AbstractGraph<?, ?> graph, int ecken){	
		Iterator<?> iterEdge = graph.edgeSet().iterator();
		while(iterEdge.hasNext()){
			Object obj = iterEdge.next();
			if(obj instanceof DefaultEdge) {
				isDefaultEgde = true;
				break;
			}else break;
		}
		Iterator<?> isVertex = graph.vertexSet().iterator();
		while(isVertex.hasNext()){
			Object obj = isVertex.next();
			if(obj instanceof String) {
				isString = true;
				break;
			}else
				break;			
		}
		 if(isDefaultEgde && isString){
			out("String && DefaultEdge " + ecken);
			AbstractGraph<String, DefaultEdge> tgraph = (AbstractGraph<String, DefaultEdge>)graph;
			preView(tgraph, ecken );	
		 }else if(isString && !isDefaultEgde){
			 out("String & DefaultWeightedEdge " + ecken);
			 AbstractGraph<String, DefaultWeightedEdge> tgraph = (AbstractGraph<String, DefaultWeightedEdge>)graph;
			 preViewGewichtet(tgraph, ecken);
		 }else{
			 out("Knoten & DefaultWeightedEdge " + ecken);
			 AbstractGraph<Knoten, DefaultWeightedEdge> tgraph = ( AbstractGraph<Knoten, DefaultWeightedEdge>) graph;
			 preViewGewichtetAttr(tgraph, ecken);
		 }
		
	}

    public ViewGraph(String titel, AbstractGraph<?, ?> graph, int ecken, boolean big){
        isBig = big;
        Iterator<?> iterEdge = graph.edgeSet().iterator();
        while(iterEdge.hasNext()){
            Object obj = iterEdge.next();
            if(obj instanceof DefaultEdge) {
                isDefaultEgde = true;
                break;
            }else break;
        }
        Iterator<?> isVertex = graph.vertexSet().iterator();
        while(isVertex.hasNext()){
            Object obj = isVertex.next();
            if(obj instanceof String) {
                isString = true;
                break;
            }else
                break;
        }
        if(isDefaultEgde && isString){
            out("String && DefaultEdge " + ecken);
            AbstractGraph<String, DefaultEdge> tgraph = (AbstractGraph<String, DefaultEdge>)graph;
            preView(tgraph, ecken );
        }else if(isString && !isDefaultEgde){
            out("String & DefaultWeightedEdge " + ecken);
            AbstractGraph<String, DefaultWeightedEdge> tgraph = (AbstractGraph<String, DefaultWeightedEdge>)graph;
            preViewGewichtet(tgraph, ecken);
        }else{
            out("Knoten & DefaultWeightedEdge " + ecken);
            AbstractGraph<Knoten, DefaultWeightedEdge> tgraph = ( AbstractGraph<Knoten, DefaultWeightedEdge>) graph;
            preViewGewichtetAttr(tgraph, ecken);
        }
    }


    public ViewGraph(String titel, AbstractGraph<?, ?> graph, int ecken, JGraphModelAdapter<?,?> adapter){
        this.graphAdapter = adapter;
        Iterator<?> iterEdge = graph.edgeSet().iterator();
        while(iterEdge.hasNext()){
            Object obj = iterEdge.next();
            if(obj instanceof DefaultEdge) {
                isDefaultEgde = true;
                break;
            }else break;
        }
        Iterator<?> isVertex = graph.vertexSet().iterator();
        while(isVertex.hasNext()){
            Object obj = isVertex.next();
            if(obj instanceof String) {
                isString = true;
                break;
            }else
                break;
        }
        if(isDefaultEgde && isString){
            out("String && DefaultEdge " + ecken);
            AbstractGraph<String, DefaultEdge> tgraph = (AbstractGraph<String, DefaultEdge>)graph;
            preView(tgraph, ecken );
        }else if(isString && !isDefaultEgde){
            out("String & DefaultWeightedEdge " + ecken);
            AbstractGraph<String, DefaultWeightedEdge> tgraph = (AbstractGraph<String, DefaultWeightedEdge>)graph;
            preViewGewichtet(tgraph, ecken);
        }else{
            out("Knoten & DefaultWeightedEdge " + ecken);
            AbstractGraph<Knoten, DefaultWeightedEdge> tgraph = ( AbstractGraph<Knoten, DefaultWeightedEdge>) graph;
            preViewGewichtetAttr(tgraph, ecken);
        }

    }

    public ViewGraph(String titel, AbstractGraph<?, ?> graph, int ecken, JGraphModelAdapter<?,?> adapter, boolean big){
        isBig = big;
        this.graphAdapter = adapter;
        Iterator<?> iterEdge = graph.edgeSet().iterator();
        while(iterEdge.hasNext()){
            Object obj = iterEdge.next();
            if(obj instanceof DefaultEdge) {
                isDefaultEgde = true;
                break;
            }else break;
        }
        Iterator<?> isVertex = graph.vertexSet().iterator();
        while(isVertex.hasNext()){
            Object obj = isVertex.next();
            if(obj instanceof String) {
                isString = true;
                break;
            }else
                break;
        }
        if(isDefaultEgde && isString){
            out("String && DefaultEdge " + ecken);
            AbstractGraph<String, DefaultEdge> tgraph = (AbstractGraph<String, DefaultEdge>)graph;
            preView(tgraph, ecken );
        }else if(isString && !isDefaultEgde){
            out("String & DefaultWeightedEdge " + ecken);
            AbstractGraph<String, DefaultWeightedEdge> tgraph = (AbstractGraph<String, DefaultWeightedEdge>)graph;
            preViewGewichtet(tgraph, ecken);
        }else{
            out("Knoten & DefaultWeightedEdge " + ecken);
            AbstractGraph<Knoten, DefaultWeightedEdge> tgraph = ( AbstractGraph<Knoten, DefaultWeightedEdge>) graph;
            preViewGewichtetAttr(tgraph, ecken);
        }

    }

	
	private void preViewGewichtet(AbstractGraph<String, DefaultWeightedEdge> graph, int ecken){		
		if(graphAdapter == null) graphAdapter = new JGraphModelAdapter<String, DefaultWeightedEdge>(graph);
		if(!isBig)init(graphAdapter, ecken);
	    else  initBig(graphAdapter, ecken);
    }
	
	private void preViewGewichtetAttr(AbstractGraph<Knoten, DefaultWeightedEdge> graph, int ecken){
        if(graphAdapter == null) graphAdapter = new JGraphModelAdapter<Knoten, DefaultWeightedEdge>(graph);
		if(!isBig)init(graphAdapter, ecken);
	    else initBig(graphAdapter, ecken);
    }
	
	
	
	private void preView(AbstractGraph<String, DefaultEdge> graph, int ecken){
        if(graphAdapter == null) graphAdapter = new JGraphModelAdapter<String, DefaultEdge>(graph);
		if(!isBig)init(graphAdapter, ecken);
	    else initBig(graphAdapter, ecken);
    }

    private void initBig(JGraphModelAdapter<?,?> graphAdapter, int ecken) {
        scrollPane.setBounds(new Rectangle(0,0,1000,850));
         for(int i = 0; i < ecken; i++){
                                                         int x = (int)(Math.random()*1000);
                                                         int y = (int)(Math.random()*1000);


             positionVertexAt(graphAdapter.getRootAt(i), x, y);
         }
        JGraph jGraph = new JGraph(graphAdapter);
        this.setSize(1000,750);
        this.add(scrollPane.getViewport().add(jGraph), BorderLayout.CENTER);
        out("With: "+scrollPane.getSize().getWidth() + " Height: " + scrollPane.getSize().getHeight());
    }

    private void init(JGraphModelAdapter<?, ?> adapter, int ecken){
		scrollPane.setBounds(new Rectangle(0,0,1000,850));
        for(int i = 0; i< ecken; i++){
			positionVertexAt(adapter.getRoots().get(i), getXWert() , getYWert());			
		}		
		JGraph jGraph = new JGraph(adapter);		
	    
	    this.setSize(1000,850);
	    
	    this.add(scrollPane.getViewport().add(jGraph), BorderLayout.CENTER);
	    System.out.println("XSet: " +	xset  + " ySet: " + ySet);	    
	}

	
	private int getXWert(){
		boolean tmp = true;
		int  x = 0;
		while(tmp){
			x = (int)(Math.random()*1000);
			if(x > 20 && x <900) 
				if(!contain(x, xset)){
					tmp = false;
					xset.add(x);
				}			
		}		
		return x;
	}
	
	private int getYWert(){
		boolean tmp = true;
		int  y = 0;
		while(tmp){
			y = (int)(Math.random()*1000);
			if(y > 20 && y<750) {
				if(!contain(y, ySet)){
					tmp = false;
					ySet.add(y);
				}			
			}
		}		
		return y;
	}
		
	private boolean contain(int x, Set<Integer> setYX){
		boolean tmp = false;
		for(int i = 0; i < 20; i++){
			if(setYX.contains(x+i) || setYX.contains(x-i)) return true;			
		}
		return tmp;
	}
	
	private void positionVertexAt(Object vertex, int x, int y ) {
            //out("----> " + vertex);
	        DefaultGraphCell cell = (DefaultGraphCell) vertex ;
	        Rectangle2D       b    =  GraphConstants.getBounds(cell.getAttributes());
	        GraphConstants.setBounds( cell.getAttributes(), new Rectangle( x, y, ((int)b.getWidth() -35), (int)b.getHeight()) );
	    }
	
	
	
	
	
	private void out(String str){
		System.out.println(str);
	}
}
